package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.entity.TownInfo;
import cn.stylefeng.guns.modular.business.enums.TownInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.TownInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.TownInfoRequest;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.guns.modular.business.service.TownClassifyService;
import cn.stylefeng.guns.modular.business.service.TownInfoService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 城镇信息表业务实现层
 *
 * @author zhangyaowen
 * @date 2021/10/25 16:46
 */
@Service
public class TownInfoServiceImpl extends ServiceImpl<TownInfoMapper, TownInfo> implements TownInfoService {

    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private SubUseBrowseService subUseBrowseService;
    @Resource
    private TownClassifyService townClassifyService;
	@Override
    public void add(TownInfoRequest townInfoRequest) {
        TownInfo townInfo = new TownInfo();
        BeanUtil.copyProperties(townInfoRequest, townInfo);
        this.save(townInfo);
    }

    @Override
    public void del(TownInfoRequest townInfoRequest) {
        TownInfo townInfo = this.queryTownInfo(townInfoRequest);
        this.removeById(townInfo.getId());
    }

    @Override
    public void edit(TownInfoRequest townInfoRequest) {
        TownInfo townInfo = this.queryTownInfo(townInfoRequest);
        BeanUtil.copyProperties(townInfoRequest, townInfo);
        this.updateById(townInfo);
    }

    @Override
    public TownInfo detail(TownInfoRequest townInfoRequest) {
        return this.queryTownInfo(townInfoRequest);
    }

    @Override
    public PageResult<TownInfo> findPage(TownInfoRequest townInfoRequest) {
        LambdaQueryWrapper<TownInfo> wrapper = createWrapper(townInfoRequest);
        Page<TownInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public List<TownInfo> findList(TownInfoRequest townInfoRequest) {
        LambdaQueryWrapper<TownInfo> wrapper = this.createWrapper(townInfoRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/10/25 16:46
     */
    private TownInfo queryTownInfo(TownInfoRequest townInfoRequest) {
        TownInfo townInfo = this.getById(townInfoRequest.getId());
        if (ObjectUtil.isEmpty(townInfo)) {
            throw new ServiceException(TownInfoExceptionEnum.TOWNINFO_NOT_EXISTED);
        }
        return townInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/10/25 16:46
     */
    private LambdaQueryWrapper<TownInfo> createWrapper(TownInfoRequest townInfoRequest) {
        LambdaQueryWrapper<TownInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = townInfoRequest.getId();
        String townName = townInfoRequest.getTownName();
        String oneClassify = townInfoRequest.getOneClassify();
        String twoClassify = townInfoRequest.getTwoClassify();
        String threeClassify = townInfoRequest.getThreeClassify();
        String historicalChronicle = townInfoRequest.getHistoricalChronicle();
        String adChronicle = townInfoRequest.getAdChronicle();
        String townIntroduction = townInfoRequest.getTownIntroduction();
        String townAnnotation = townInfoRequest.getTownAnnotation();
        String townAnnalsfrom = townInfoRequest.getTownAnnalsfrom();
        Long townAnnalspage = townInfoRequest.getTownAnnalspage();

        queryWrapper.eq(ObjectUtil.isNotNull(id), TownInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(townName), TownInfo::getTownName, townName);
        queryWrapper.like(ObjectUtil.isNotEmpty(oneClassify), TownInfo::getOneClassify, oneClassify);
        queryWrapper.like(ObjectUtil.isNotEmpty(twoClassify), TownInfo::getTwoClassify, twoClassify);
        queryWrapper.like(ObjectUtil.isNotEmpty(threeClassify), TownInfo::getThreeClassify, threeClassify);
        queryWrapper.like(ObjectUtil.isNotEmpty(historicalChronicle), TownInfo::getHistoricalChronicle, historicalChronicle);
        queryWrapper.like(ObjectUtil.isNotEmpty(adChronicle), TownInfo::getAdChronicle, adChronicle);
        queryWrapper.like(ObjectUtil.isNotEmpty(townIntroduction), TownInfo::getTownIntroduction, townIntroduction);
        queryWrapper.like(ObjectUtil.isNotEmpty(townAnnotation), TownInfo::getTownAnnotation, townAnnotation);
        queryWrapper.like(ObjectUtil.isNotEmpty(townAnnalsfrom), TownInfo::getTownAnnalsfrom, townAnnalsfrom);
        queryWrapper.eq(ObjectUtil.isNotNull(townAnnalspage), TownInfo::getTownAnnalspage, townAnnalspage);

        return queryWrapper;
    }

    @Override
    public Map<String, Object> toReview(String jmid) {
        byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(jmid, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YHSJ后面真实的的id
        String ids = StrUtil.subAfter(decryptStr, YunHeKey.YHCZ, false);
        String[] value = {};
        if (!ids.equals("")) {
            value = StrUtil.splitToArray(ids, "-");
        }
        String id = "";
        String name = value[0];
        if (value.length > 1) {
            id = value[1];
        }
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid;
        if (ObjectUtil.isNotNull(request)) {
            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(TownInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<TownInfo> queryWrapper = new LambdaQueryWrapper<>();
        if (value.length > 1) {
            if ("".equals(name) || "".equals(id)) {
                Map<String, Object> mapLists = new HashMap<>();
                return mapLists;
            }
        }
        if ("".equals(name)) {
            Map<String, Object> mapLists = new HashMap<>();
            return mapLists;
        }
        queryWrapper.eq(ObjectUtil.isNotEmpty(name), TownInfo::getTownName, name);
        if (value.length > 1) {
            queryWrapper.eq(ObjectUtil.isNotEmpty(id), TownInfo::getId, id);
        }
        List<TownInfo> townInfoList = this.list(queryWrapper);
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.CHENGZ,townInfoList.get(0).getAdTitle(),userid,request);
        }
        //获取对应城镇的一级分类的数据
//        List<Map<String,Object>> oneClassifyList=  findOneClassify(name);

        List<Map<String, Object>> mapList = new ArrayList<>();

        List<Map<String, Object>> oneList = new ArrayList<>();
        Map<String, Object> objectMap = new HashMap<>();
        String titles = "";
        int i = 0;
        int j = 0;
        objectMap.put("survey", "");
        Map<String, Object> maps = new HashMap<>();
        if (value.length > 1) {

            for (TownInfo townInfo : townInfoList) {
                Map<String, Object> map = new HashMap<String, Object>();
                map = JSONObject.parseObject(JSONObject.toJSONString(townInfo), Map.class);
                // 获取类的属性
                Field[] declaredFields = TownInfo.class.getDeclaredFields();
                List<Map<String, Object>> mplist = new ArrayList<>();
                // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
                if (declaredFields.length != 0) {

                    int r = 1;
                    Map<String, Object> p = new HashMap<String, Object>();
                    for (Field field : declaredFields) {

                        Map<String, Object> mp = new HashMap<String, Object>();
                        if (field.getAnnotation(ApiModelProperty.class) != null) {
                            //获取注解属性
                            ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                            // key和value可根据需求存
                            // 这存的key为注解的值，value为类属性名
                            if ("townIntroduction".equals(field.getName()) || "adTitle".equals(field.getName())) {
                                if ( "adTitle".equals(field.getName()) ) {
                                    p.put("title",  map.get(field.getName()));
                                }else {
                                    p.put(field.getName(), map.get(field.getName()));
                                }
                            }else{
                                mp.put("key", aa.value());
                                mp.put("value", map.get(field.getName()));

                                if (r != 1) {
                                    mplist.add(mp);
                                }
                            }

                        }
                        r++;
                    }
                    p.put("list", mplist);
                    if (r != 1) {
                        mapList.add(p);
                    }
                }

            }
            maps.putAll(mapList.get(0));
            return maps;

        }else {
            for (TownInfo townInfo : townInfoList) {
                Map<String, Object> map1 = new HashMap<>();
                Map<String, Object> oneMap = new HashMap<>();
                List<Map<String, Object>> list = new ArrayList<>();
                if ("概况".equals(townInfo.getOneClassify())) {
                    objectMap.put("survey", objectMap.get("survey") + townInfo.getTownIntroduction());
                } else {

                    if (i == 0) {
                        titles = townInfo.getOneClassify();
                    }
                    String jm = YunHeKey.YHCZ + townInfo.getTownName() + "-" + townInfo.getId();
                    String encryptHex = aes.encryptHex(jm);
                    oneMap.put("id", encryptHex);
                    oneMap.put("title", townInfo.getAdTitle());
                    oneMap.put("oneClassify", townInfo.getOneClassify());
                    oneMap.put("from", townInfo.getTownAnnalsfrom());
                    if (titles.equals(townInfo.getOneClassify())) {
                        oneList.add(oneMap);

                    } else {
                        List<Map<String, Object>> mapLists = new ArrayList<>();
                        mapLists.addAll(oneList);
                        map1.put("key", mapLists.get(0).get("oneClassify"));
                        map1.put("list", mapLists);
                        mapList.add(map1);
                        oneList.clear();
                        oneList.add(oneMap);
                        titles = townInfo.getOneClassify();
                    }
                    if (i < 1) {
                        i++;
                    }

                }
            }
            Map<String, Object> map2 = new HashMap<>();

            if(!oneList.isEmpty() && !"".equals(titles)) {
                map2.put("key", titles);
                map2.put("list", oneList);
                mapList.add(map2);
            }

            objectMap.put("allList", mapList);
            return objectMap;
        }
    }



    public List<Map<String,Object>> findOneClassify(String townName) {
        LambdaQueryWrapper<TownInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(ObjectUtil.isNotEmpty(townName), TownInfo::getTownName, townName);

        List<Map<String,Object>> mapList = new ArrayList<>();
        List<TownInfo> lists= this.list(queryWrapper);
        for(TownInfo townInfo : lists){

            Map<String, Object> map = new HashMap<String, Object>();
            if(!townInfo.getOneClassify().equals("")){
                map.put("oneClassify",townInfo.getOneClassify());
                mapList.add(map);
            }
        }
        //List<map>去重 生成新的list
        ArrayList<Map<String, Object>> towns = mapList.stream()
                .collect(Collectors
                        .collectingAndThen(Collectors
                                .toCollection(() -> new TreeSet<>(new Comparator<Map<String, Object>>() {
                                    @Override    //重写比较器
                                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                                        if (o1.get("oneClassify").equals(o2.get("oneClassify"))) {
                                            return 0;
                                        }
                                        return 1;
                                    }

                                })), ArrayList::new));

        return towns;
    }


    @Override
    public List<Map<String,Object>> findAllList(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<TownInfo> wrapper = createWrapperByTown(riverList,townList,times,name);
        List<TownInfo>  list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(TownInfo townInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
            String jm="";
            if ("概况".equals(townInfo.getOneClassify())) {
                jm = YunHeKey.YHCZ + townInfo.getTownName();
                map.put("title", townInfo.getTownName());
            } else {
                jm = YunHeKey.YHCZ+townInfo.getTownName() + "-" + townInfo.getId();
                map.put("title", townInfo.getAdTitle());
            }



            map.put("historyDating",townInfo.getHistoricalChronicle());
            map.put("theCommon",townInfo.getAdChronicle());
            map.put("from",townInfo.getTownAnnalsfrom() );
            map.put("createTime", DateUtil.format(townInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.YHCZ);
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

//            String jmid = YunHeKey.YHCZ+townClassifyService.findCode(townInfo.getTownName());
            String encryptHex = aes.encryptHex(jm);
            map.put("id",encryptHex);
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<TownInfo> createWrapperByTown(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<TownInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), TownInfo::getHistoricalChronicle, name).or()
                .like(ObjectUtil.isNotNull(name), TownInfo::getHistoricalChronicle, name).or()
                .like(ObjectUtil.isNotNull(name), TownInfo::getAdTitle, name).or()
                .like(ObjectUtil.isNotNull(name), TownInfo::getTownAnnalsfrom, name).or());
        if( !riverList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < riverList.size(); i++) {
                    String dicAname = riverList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicAname), TownInfo::getXgRiver, dicAname);
                    if (i != riverList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( !townList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < townList.size(); i++) {
                    String dicZname = townList.get(i).getDicZname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicZname), TownInfo::getXgTown, dicZname);
                    if (i != townList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( times.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < times.length; i++) {
                    String time = times[i];
                    wrapper.like(ObjectUtil.isNotEmpty(time), TownInfo::getThreeClassify, time);
                    if (i != times.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        return queryWrapper;
    }

}